import { useCallback, useState } from 'react';
import { debounce } from 'lodash';

interface PagingInfo {
  page: number;
  pageSize?: number;
  page_size?: number;
  searchText: string;
  total: number;
  offset: number;
  [key: string]: any;
}

interface TableProps<T> {
  list: T[];
  offset: number;
  page_size?: number;
  pageSize?: number;
  total: number;
}

const useTable = <T, U extends PagingInfo = PagingInfo>(
  api: (data: U) => Promise<TableProps<T>>,
  initPagingInfo?: U,
  initTablesValue?: T[],
) => {
  const [pagingInfo, setPagingInfo] = useState<U>(
    initPagingInfo ??
    ({
      page: 1,
      pageSize: 10,
      searchText: '',
      total: 0,
      offset: -1,
    } as unknown as U),
  );
  const [searchText, setSearchText] = useState('');
  const [tablesValue, setTablesValue] = useState<T[]>(initTablesValue ?? []);
  const [loading, setLoading] = useState(false);
  const [firstEntry, setFirstEntry] = useState(true);

  const handleSearchTextFn = useCallback(
    debounce((text) => {
      getTables({ ...pagingInfo, searchText: text });
    }, 500),
    [],
  );

  const handleSearchText = (text: string) => {
    setSearchText(text);
    handleSearchTextFn(text);
  };

  const handleSearchTextInit = (text: string) => {
    setSearchText(text);
  };

  const getTables = (paging?: U) => {
    setLoading(true);
    const getTablesValue = paging || pagingInfo;
    api(getTablesValue)
      .then((res) => {
        setTablesValue(res.list);
        setPagingInfo({
          ...pagingInfo,
          page_size: res.page_size || res.pageSize || getTablesValue.page_size,
          pageSize: res.page_size || res.pageSize || getTablesValue.page_size,
          total: res.total,
          offset: res.offset,
          page: getTablesValue.page,
        });
      })
      .catch((e) => {
        console.log(e);
      })
      .finally(() => {
        setLoading(false);
        setFirstEntry(false);
      });
  };

  return {
    handleSearchText,
    getTables,
    searchText,
    tablesValue,
    loading,
    pagingInfo,
    setTablesValue,
    handleSearchTextInit,
    firstEntry,
  };
};

export default useTable;
